package com.ztesoft.sca.service;

import com.ztesoft.sca.controller.V3ToWav;
import com.ztesoft.sca.dao.IomManageDao;
import com.ztesoft.sca.dao.ThreadManageDao;
import com.ztesoft.sca.model.AudioSourceDto;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;
import java.util.Map;

@Service
public class IvrConvertServiceImpl implements IvrConvertService{
    protected final Logger logger = LoggerFactory.getLogger(this.getClass());
    @Autowired
    private IomManageDao iomManageDao;
    @Autowired
    private ThreadManageDao threadManageDao;
    private ThreadLocal<FTPClient> ftpClientThreadLocal = new ThreadLocal<>();


    private void loginFtp(String userName, String password, String ip, int port) throws IOException {
        getFtpClient().setDefaultTimeout(10000 * 30);
        getFtpClient().setDefaultPort(port);
        getFtpClient().connect(ip);
        getFtpClient().login(userName, password);
        getFtpClient().enterLocalPassiveMode();
    }

    private void closeFtp() throws IOException {
        try{
            getFtpClient().logout();
        }catch(Exception e){
            e.printStackTrace();
        }
        try{
            getFtpClient().disconnect();
        }catch(Exception e){
            e.printStackTrace();
        }
        ftpClientThreadLocal.remove();
    }

    private FTPClient getFtpClient() {
        if (ftpClientThreadLocal.get() == null) {
            ftpClientThreadLocal.set(new FTPClient());
        }
        return ftpClientThreadLocal.get();
    }

    @Override
    public List<Map> listIvrRecord() throws Exception {
        return iomManageDao.listIvrRecord();
    }

    @Override
    public Map downloadIvrFile(Map order) throws Exception {
        FileOutputStream fos = null;
        String fileName="";
        try {

            //ivr下载地址
            Map dlFtpPath = threadManageDao.qryOsPublic("IVR_VOICE_PATH_DOWNLOAD",null);
            //本机储存地址
            Map localPathMap = threadManageDao.qryOsPublic("IVR_LOCAL_VOICE_PATH",null);

            if (null == dlFtpPath || "".equals(dlFtpPath)) {
                throw new Exception("ftp文件路径为空!");
            }
            int port = 21;


            String path =MapUtils.getString(dlFtpPath, "CODEB")+MapUtils.getString(order, "file_path");
            String localSavePath=MapUtils.getString(localPathMap, "CODEA")+MapUtils.getString(order, "file_path");
            int voxFormat=MapUtils.getIntValue(localPathMap, "CODEB");
            int voxRate=MapUtils.getIntValue(localPathMap, "CODEC");
            int bitRate=MapUtils.getIntValue(localPathMap, "CODED");

//			// 配置代理ftp地址就用代理地址
//			if (null != ftpProxy && !"".equals(ftpProxy)) {
//				ip = ftpProxy;
//			}
            /************************下载开始 ********************************/
            String dlUserName = MapUtils.getString(dlFtpPath, "CODEC");
            String dlPassword = MapUtils.getString(dlFtpPath, "CODED");
            String dlIp = MapUtils.getString(dlFtpPath, "CODEA");
            logger.debug("----下载ftp: username=" + dlUserName + ",password=" + dlPassword + ",ip=" + dlIp + ",port=" + port);

            logger.info("下载  "+MapUtils.getString(order, "file_path"));
            // 登录
            loginFtp(dlUserName, dlPassword, dlIp, port);

            File localFile = new File(localSavePath);
            if(!localFile.getParentFile().exists()){
                logger.info("=======本地目录不存在，创建目录=========");
                localFile.getParentFile().mkdirs();
            }

            fileName=localFile.getName();

            fos = new FileOutputStream(localSavePath);
            logger.debug("===========remoteFileName:" + path);
            logger.debug("===========localPath:" + localSavePath);

            //new String(path.getBytes("GBK"), "ISO-8859-1")
            boolean isSuccess=getFtpClient().retrieveFile(path, fos);
            fos.flush();
            fos.close();
            logger.debug("===========获取完毕");


            /************************下载结束 ********************************/

            order.put("localSavePath",localSavePath);
            order.put("voxFormat",voxFormat);
            order.put("voxRate",voxRate);
            order.put("bitRate",bitRate);

        } catch (Exception e) {
            logger.error("下载文件失败! 文件：" +fileName, e);
            e.printStackTrace();
            throw new Exception("转换文件异常," + e.getMessage());
        } finally {
            try{
                IOUtils.closeQuietly(fos);
            }catch(Exception e){
                e.printStackTrace();
            }
            try{
                // 登出
                closeFtp();
            }catch(Exception e){
                e.printStackTrace();
            }
        }
        return order;

    }

    @Override
    public Map convertIvrFile(Map param) throws Exception {
        String localSavePath=MapUtils.getString(param,"localSavePath");
        try {


            //格式 取值范围:VF_ADPCM = 1, VF_MULAW = 2, VF_ALAW = 3
            int voxFormat=MapUtils.getIntValue(param,"voxFormat");
            //采样率 取值范围：VR_6K = 6000, VR_8K = 8000
            int voxRate=MapUtils.getIntValue(param,"voxRate");
            //位数 取值范围：VB_8 = 1, VB_16 = 2
            int bitRate=MapUtils.getIntValue(param,"bitRate");

            /************************转换开始 ********************************/
            //转码
            localSavePath=V3ToWav.voxConvert(localSavePath, null, voxFormat, voxRate, bitRate);
            logger.debug("===========转码完毕" + localSavePath);

            /************************转换结束 ********************************/

            param.put("localSavePath",localSavePath);

        } catch (Exception e) {
            logger.error("转换文件失败! 文件："+localSavePath , e);
            e.printStackTrace();
            throw new Exception("转换文件异常," + e.getMessage());
        }
        return param;
    }

    @Override
    public Map uploadIvrFile(Map param) throws Exception {

        FileInputStream fis= null;
        String localSavePath=MapUtils.getString(param,"localSavePath");
        try {

            //上传地址
            Map ulFtpPath = threadManageDao.qryOsPublic("IVR_VOICE_PATH_UPLOAD",null);
            int port = 21;


            /************************上传开始 ********************************/
            String oldPath=MapUtils.getString(param, "file_path");

            String ulUserName = MapUtils.getString(ulFtpPath, "CODEC");
            String ulPassword = MapUtils.getString(ulFtpPath, "CODED");
            String ulIp = MapUtils.getString(ulFtpPath, "CODEA");
            String ulPathPreFix=MapUtils.getString(ulFtpPath, "CODEB");
            //String ulPath=MapUtils.getString(ulFtpPath, "CODEB")+oldPath.substring(0,oldPath.length()-3)+"wav";
            String visitPath=MapUtils.getString(ulFtpPath, "CODEE")+oldPath.substring(0,oldPath.length()-3)+"wav";
            logger.debug("----上传ftp: username=" + ulUserName + ",password=" + ulPassword + ",ip=" + ulIp + ",port=" + port);

            loginFtp(ulUserName, ulPassword, ulIp, port);

            File ulFile=new File(oldPath.substring(0,oldPath.length()-3)+"wav");

            getFtpClient().changeWorkingDirectory(ulPathPreFix);
            if(!getFtpClient().changeWorkingDirectory(ulFile.getParentFile().getName())){
                getFtpClient().makeDirectory(ulFile.getParentFile().getName());
                getFtpClient().changeWorkingDirectory(ulFile.getParentFile().getName());
            }

            fis= new FileInputStream(localSavePath);
            getFtpClient().enterLocalPassiveMode();
            //getFtpClient().setFileType(FTP.BINARY_FILE_TYPE);
            getFtpClient().setDataTimeout(30000);
            boolean isSuccess=getFtpClient().storeFile(ulFile.getName(), fis);
            logger.debug("===========上传完毕");
            /************************上传结束 ********************************/

            IOUtils.closeQuietly(fis);

            rmLocalIvrFile(localSavePath);
            rmLocalIvrFile(localSavePath.substring(0,localSavePath.length()-3)+"vox");

            String fileName=MapUtils.getString(param, "file_name");
            param.put("file_path", visitPath);
            param.put("file_name", fileName.substring(0,fileName.length()-3)+"wav");

            param.put("serverIp", ulIp);
            param.put("serverName", ulUserName);
            param.put("serverPassword", ulPassword);


        } catch (Exception e) {
            logger.error("上传文件失败! 文件："+localSavePath , e);
            e.printStackTrace();
            throw new Exception("转换文件异常," + e.getMessage());
        } finally {

            try{
                IOUtils.closeQuietly(fis);
            }catch(Exception e){
                e.printStackTrace();
            }
            try{
                // 登出
                closeFtp();
            }catch(Exception e){
                e.printStackTrace();
            }
        }

        return param;

    }


    @Override
    public boolean rmLocalIvrFile(String path) throws Exception {
        boolean isSuccess=true;
        try{
            File localFile = new File(path);
            isSuccess=localFile.delete();
            logger.debug("===========删除零时文件完成");
        }catch(Exception e){
            logger.error("删除零时文件失败! 文件：" + path, e);
            e.printStackTrace();
        }
        return  isSuccess;
    }

    @Override
    public void addIomConvertRecord(Map param) throws Exception {
        iomManageDao.addConvertRecord(param);
    }

    @Override
    public void updateIomConvertRecord(Map param) throws Exception {
        iomManageDao.updateConvertRecord(param);
    }

    @Override
    public void addScaAudioSource(Map param) throws Exception {

        int voxRate=MapUtils.getIntValue(param,"voxRate");

        Map orderInfo=iomManageDao.qryOrderInfo(MapUtils.getLong(param,"id"));
        AudioSourceDto audioSourceDto=new AudioSourceDto();
        audioSourceDto.setFileName(MapUtils.getString(param,"file_name"));
        audioSourceDto.setFilePath(MapUtils.getString(param,"file_path"));

        audioSourceDto.setServerIp(MapUtils.getString(param,"serverIp"));
        audioSourceDto.setServerName(MapUtils.getString(param,"serverName"));
        audioSourceDto.setServerPassword(MapUtils.getString(param,"serverPassword"));
        audioSourceDto.setFormat("wav");

        audioSourceDto.setSampleRate(String.valueOf(voxRate/1000));
        //audioSourceDto.setDescpiption(MapUtils.getString(order,"file_name"));
        //audioSourceDto.setRequestAction(MapUtils.getString(order,"file_name"));
        audioSourceDto.setStatus("0");

        audioSourceDto.setCallTime(MapUtils.getString(orderInfo,"CALL_TIME"));
        audioSourceDto.setBookTime(MapUtils.getString(orderInfo,"BOOK_TIME"));
        audioSourceDto.setBookEndTime(MapUtils.getString(orderInfo,"BOOK_END_TIME"));
        audioSourceDto.setHandupTime(MapUtils.getString(orderInfo,"HANDUP_TIME"));
        audioSourceDto.setHandupEndTime(MapUtils.getString(orderInfo,"HANDUP_END_TIME"));
        audioSourceDto.setOrderStatus(MapUtils.getString(orderInfo,"ORDER_STATUS"));
        audioSourceDto.setOrderId(MapUtils.getString(param,"order_id"));
        threadManageDao.insertScaAudioSource(audioSourceDto);
    }
}
